<?php
declare (strict_types=1);

namespace app\common\model;

use app\common\facade\Target;
use think\facade\Cache;
use think\facade\Event;

class Order extends Base
{
    protected function user()
    {
        return $this->hasOne(User::class, 'id', 'uid')->field('id,code,nickname,mobile');
    }

    protected function express()
    {
        return $this->hasOne(Express::class, 'id', 'express_id');
    }

    protected function p()
    {
        return $this->hasOne(Area::class, 'code', 'province')->field('code,province as title');
    }

    protected function c()
    {
        return $this->hasOne(Area::class, 'code', 'city')->field('code,city as title');
    }

    protected function d()
    {
        return $this->hasOne(Area::class, 'code', 'district')->field('code,district as title');
    }

    protected function products()
    {
        return $this->hasMany(OrderProduct::class, 'order_id');
    }

    protected function getStatusAttr($value)
    {
        return getOrderStatus($value);
    }

    protected function getPayWayAttr($value)
    {
        return get_pay_way($value);
    }

    protected function getPostTimeAttr($value)
    {
        return $value ? date('Y-m-d H:i:s', $value) : '';
    }

    public static function getTakeOverTableList($that, $param, $filed = '*', $count = 0)
    {
        try {
            foreach ($that as &$v) {
                $products = $v->products()->field('pid,product_title,num')->select()->toArray();
                foreach ($products as $item) {
                    $v->product .= $item['product_title'] . ' ' . '数量：' . $item['num'] . "\n";
                }
                $v->pay_time = $v->pay_time ? date('Y-m-d H:i:s', intval($v->pay_time)) : '待支付';
                $v->statusRaw = $v->getData('status');
            }
            return ['code' => 0, 'data' => $that, 'count' => $count];
        } catch (\Exception $e) {
            return [];
        }
    }

    /**
     * @param $param -- 提交的参数
     * @param $admin -- 后台当前登录管理员
     * @return array
     * 原点 2022年1月8日16:45:49 后台发货订单
     */
    public static function deliver($param, $admin): array
    {
        try {
            $info = parent::find($param['id']);
            if ($info->isEmpty()) {
                throw new \Exception('未查询到相关订单');
            }
            $status = $info->status;
            $info->express_id = $param['express_id'];
            $info->express_code = $param['express_code'];
            $info->receiver = $param['receiver'];
            $info->receiver_tel = $param['receiver_tel'];
            $info->province = $param['province'];
            $info->city = $param['city'];
            $info->district = $param['district'];
            $info->address_details = $param['address_details'];
            $info->post_remark = $param['post_remark'];
            $info->post_time = time();

            $info->status = 3;
            $res = $info->save();
            if ($res !== true) {
                throw new \Exception('发货失败');
            }
            if ($status < 3) {
                $log = '订单发货，订单号【' . $info->sn . '】下单会员【' . $info->user->code . '】';
                $msg = '已发货';
            } else {
                $log = '修改了发货信息，订单号【' . $info->sn . '】下单会员【' . $info->user->code . '】';
                $msg = '已修改';
            }
            Logs::adds($log, $admin->id, $admin->admin_name);

        } catch (\Exception $e) {

            return ['code' => -1, 'msg' => $e->getMessage()];
        }

        return ['code' => 1, 'msg' => $msg];
    }

    /**
     * 获得会员临时暂存的订单
     */
    public static function getTemporary($user): array
    {
        try {
            $temporary = Cache::get('tsOrder_' . $user->id);
            if (empty($temporary)) {
                return [];
            }
            $infos = json_decode($temporary, true);
            $cate_1 = $total = $num = 0;
            $products = [];
            foreach ($infos as $value) {
                $product = Product::where(['id' => $value['pid'], 'status' => 1, 'is_del' => 0])->find();
                if (empty($product) || $product->stock <= 0) continue;
                $cate_1 = $value['cate_1'];
                $total += round($product->price * $value['num'], 2);
                $num += $value['num'];
                $product->num = $value['num'];
                $products[] = $product;
            }
            return [
                'cate_1' => $cate_1,
                'total' => sprintf('%.2f', $total),
                'num' => $num,
                'address' => Address::getDefault($user->id),
                'products' => $products
            ];

        } catch (\Exception $e) {

            return [];
        }
    }

    /**
     * @param $address_id -- 选择地址ID
     * @param $user -- 会员信息
     * @return array
     * 原点 2022年1月8日16:44:54 提交产生待支付订单
     */
    public static function submit($param, $user): array
    {
        $temporary = self::getTemporary($user);
        if (empty($temporary) || empty($temporary['products'])) {
            return ['code' => -1, 'msg' => '加载失败，请稍后再试'];
        }
        if (!$temporary['total'] || $temporary['total'] <= 0) {
            return ['code' => -1, 'msg' => '订单价格错误！'];
        }
        if (!$param['address_id']) {
            return ['code' => -1, 'msg' => '请选择收货地址'];
        }
        $address = Address::where(['id' => $param['address_id']])->find();
        if (!$address) {
            return ['code' => -1, 'msg' => '收货地址错误，请重新选择'];
        }
        $data = [
            'sn' => 'T' . date('YmdHis') . rand(100000, 999999) . $user->id,
            'uid' => $user->id,
            'order_type' => $temporary['cate_1'],
            'total_amount' => $temporary['total'],
            'real_amount' => $temporary['total'],
            'num' => $temporary['num'],
            'address_id' => $address->id,
            'receiver' => $address->nickname,
            'receiver_tel' => $address->tel,
            'province' => $address->province,
            'city' => $address->city,
            'district' => $address->district,
            'address_details' => $address->details,
            'remark' => $param['remark']
        ];
        parent::startTrans();
        try {
            $new = parent::create($data);
            $id = $new->id;
            $res = OrderProduct::add($temporary['products'], $id);
            if ($res !== true) {
                throw new \Exception($res);
            }

            parent::commit();
            Cart::clearCart($user->id);
        } catch (\Exception $e) {
            parent::rollback();

            return ['code' => -1, 'msg' => $e->getMessage()];
        }

        return ['code' => 1, 'msg' => '已生成订单', 'order_id' => $id, 'url' => url('order/payment')->build() . '?id=' . $id];
    }

    /**
     * @param $param -- 支付提交参数
     * @param $user -- 会员信息
     * @return array
     * 原点 2022年1月8日16:42:30 确认支付
     */
    public static function confirmPayment($param, $user): array
    {
        $info = parent::where(['id' => $param['id'], 'uid' => $user->id, 'status' => 1, 'pay_state' => 1])->find();
        if (!$info) {
            return ['code' => -1, 'msg' => '订单不存在或已支付'];
        }
        $account = $param['pay_way'];
        switch ($account) {
            case "balance":
                if ($user->assets->$account < $info->real_amount) {
                    return ['code' => -1, 'msg' => get_pay_way($account) . '账户余额不足'];
                }
                return self::operation($info, $user, $account);
            default:
                return ['code' => -1, 'msg' => '请选择支付方式'];
        }
    }

    /**
     * @param $order -- 订单信息
     * @param $user -- 会员信息
     * @param $pay_way -- 支付方式
     * @return array
     * 原点 2022年1月8日16:42:02 支付完成后续操作
     */
    public static function operation($order, $user, $pay_way): array
    {
        parent::startTrans();
        try {
            $time = time();
            //更改状态
            $order->pay_state = 2;
            $order->pay_way = $pay_way;
            $order->status = 2;
            $order->pay_time = $time;
            //扣钱
            if (!in_array($pay_way, ['wechat', 'alipay'])) {
                Target::Account()->basics($user->id, $pay_way, $order->real_amount, '购买商品', '-')
                    ->createNormal();
            }
            $order->save();
            $user->my_total += $order->real_amount;
            $user->save();
            Relation::renewTeamTotal($user->id, $order->real_amount);
            Event::trigger('Statistics', ['key' => 'income', 'value' => $order->real_amount]);
            Event::trigger('Operation', $order->id);

            parent::commit();
        } catch (\Exception $e) {
            parent::rollback();

            return ['code' => -1, 'msg' => $e->getMessage()];
        }

        return ['code' => 1, 'msg' => '支付成功', 'url' => url('order/my_order')->build()];
    }

    /**
     * @param $param
     * @param $user
     * @return array
     * 原点 2022年1月8日16:43:09 订单相关操作
     */
    public static function edit($param): array
    {
        try {
            $info = parent::where(['id' => $param['id'], 'is_del' => 0])->find();
            if (empty($info)) {
                return ['code' => -1, 'msg' => '订单不存在'];
            }
            $time = time();
            switch ($param['type']) {
                case 'clear': //取消订单
                    if ($info->getData('status') != 1 || $info->pay_state != 1) {
                        return ['code' => -1, 'msg' => '订单已支付，无法取消'];
                    }
                    $info->is_del = 1;
                    $info->status = 6;
                    $info->cancel_time = $time;
                    $info->save();

                    return ['code' => 1, 'msg' => '订单已取消'];
                case "remind": //提醒发货
                    if ($info->getData('status') != 2) {
                        return ['code' => -1, 'msg' => '订单未支付或已发货'];
                    }
                    if ($info->is_remind) {
                        return ['code' => -1, 'msg' => '您已提醒发货了！'];
                    }
                    $info->is_remind = 1;
                    $info->remind_time = $time;
                    $info->save();

                    return ['code' => 1, 'msg' => '已提醒发货'];
                case "receipt": //确认收货
                    if ($info->getData('status') != 3) {
                        return ['code' => -1, 'msg' => '订单异常'];
                    }
                    $time = time();
                    $info->status = 5;
                    $info->receipt_time = $time;
                    $info->finish_time = $time;
                    $info->save();

                    return ['code' => 1, 'msg' => '已确认收货'];
                default:

                    return ['code' => -1, 'msg' => '加载失败'];
            }

        } catch (\Exception $e) {

            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }
}